package com.gmu.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gmu.domain.ResResult;
import com.gmu.domain.vo.BeSampleUnitsActivitiesVo;
import com.gmu.domain.vo.PageVo;
import com.gmu.pojo.BeSampleUnitsActivities;
import com.gmu.mapper.BeSampleUnitsActivitiesMapper;
import com.gmu.service.BeSampleUnitsActivitiesService;


import com.gmu.mapper.*;
import com.gmu.pojo.*;
import com.gmu.service.TblOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;


/**
 * <p>
 * 被采样单位活动表 服务实现类
 * </p>
 *
 * @author testjava
 * @since 2022-07-24
 */
@Service
public class BeSampleUnitsActivitiesServiceImpl extends ServiceImpl<BeSampleUnitsActivitiesMapper, BeSampleUnitsActivities> implements BeSampleUnitsActivitiesService {


    @Autowired
    private BeSampleUnitsActivitiesMapper beSampleUnitsActivitiesMapper;

    @Autowired
    private TblActivitiesMapper tblActivitiesMapper;

    @Autowired
    private TblUserMapper tblUserMapper;

    @Autowired
    private TblUnitsMapper tblUnitsMapper;

    @Autowired
    private TblActivitiesAddressMapper tblActivitiesAddressMapper;

    @Autowired
    private TblOrderMapper tblOrderMapper;

    @Autowired
    private TblSampleAddressMapper tblSampleAddressMapper;

    @Autowired
    private TblOrderService tblOrderService;

    @Autowired
    private BeSampleUnitsActivitiesService beSampleUnitsActivitiesService;

    @Override
    public ResResult<?> showReservationAddress(Integer activitiesId) {
        List<TblSampleAddress> list = beSampleUnitsActivitiesMapper.showReservationAddress(activitiesId);
        return new ResResult<>(200, list);
    }

    @Override
    public ResResult<?> getTimeStamp(Integer activitiesId,Integer addressId,Integer activitiesAddressId) {
        List<BeSampleUnitsActivities> list = beSampleUnitsActivitiesMapper.getTimeStamp(activitiesId,addressId,activitiesAddressId);
        return new ResResult<>(200,list);
    }


    /**
     * 进行活动的选择(不可预约)(自动分配)
     *
     * @param activitiesId 活动id
     * @param peoples      可预约人数
     * @return
     * @throws ParseException
     */
    @Override
    @Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class)//事务：读取已提交数据(会出现不可重复读和幻读)
    public ResResult<?> unitsSelectActivities(Integer activitiesId, Integer unitsId, Integer peoples, Integer intervalTime) throws ParseException {

        //通过activitiesId查找对应的活动
        TblActivities tblActivities = tblActivitiesMapper.selectById(activitiesId);
        if (Objects.isNull(tblActivities)) {
            return new ResResult<>(404, "未找到该次活动");
        }

        //通过活动id查找对应的采样地点
        List<TblSampleAddress> tblSampleAddresses = beSampleUnitsActivitiesMapper.showReservationAddress(activitiesId);
        if (CollectionUtils.isEmpty(tblSampleAddresses)){
            return new ResResult<>(500,"请先设置本次活动的窗口号");
        }

        List<TblActivitiesAddress> tblActivitiesAddresses = new ArrayList<>();
        for (TblSampleAddress tblSampleAddress : tblSampleAddresses) {
            //获取活动对应的地点
            List<TblActivitiesAddress> tblActivitiesAddresses_ = tblActivitiesAddressMapper.getWindowsById(activitiesId, tblSampleAddress.getAddressId());
            tblActivitiesAddresses.addAll(tblActivitiesAddresses_);
        }

        //将 窗口号*时间段 插入be_sample_units_activities表
        insertBeSampleUnitsActivities(tblActivities, unitsId, tblActivitiesAddresses, peoples, intervalTime, 0);//0-不可预约

        //查找被采样单位的所有叶子节点
        List<TblUnits> tblUnits = tblUnitsMapper.selectUnitsChildren(unitsId);
        //获取单位对应的用户
        LinkedList<TblUser> tblUsers = selectUserByUnitsId(tblUnits);

        //查找到所有该活动id对应的被采样单位活动表的记录
        LambdaQueryWrapper<BeSampleUnitsActivities> wrapper2 = new LambdaQueryWrapper<>();
        wrapper2.eq(BeSampleUnitsActivities::getActivitiesId, activitiesId);
        List<BeSampleUnitsActivities> beSampleUnitsActivities = beSampleUnitsActivitiesMapper.selectList(wrapper2);

        //将用户与采样活动进行一对一插入tbl_order表
        return insertTblOrder(beSampleUnitsActivities, peoples, tblUsers);
    }

    /**
     * 单位进行活动选择(不可预约)(手动分配)
     *
     * @param activitiesId 活动id
     * @param peoples      可预约人数
     * @param addressId    采样地点id
     * @param unitsIds     单位id
     * @return
     */
    @Override
    @Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class)//事务：读取已提交数据(会出现不可重复读和幻读)
    public ResResult<?> unitsDistributeActivities(Integer activitiesId, Integer unitsId, Integer peoples, Integer addressId, Integer[] unitsIds, Integer intervalTime) throws ParseException {

        //通过activitiesId查找对应的活动
        TblActivities tblActivities = tblActivitiesMapper.selectById(activitiesId);
        if (Objects.isNull(tblActivities)) {
            return new ResResult<>(404, "未找到该次活动");
        }

        //根据 活动id和采样地点id 查找到对应的窗口号
        HashMap<String, Integer> map = new HashMap<>();
        map.put("activities_id", activitiesId);
        map.put("sample_address_id", addressId);
        QueryWrapper<TblActivitiesAddress> wrapper = new QueryWrapper<>();
        wrapper.allEq(map);
        List<TblActivitiesAddress> tblActivitiesAddresses = tblActivitiesAddressMapper.selectList(wrapper);
//        List<TblActivitiesAddress> tblActivitiesAddresses = tblActivitiesAddressMapper.getWindowsById(activitiesId, addressId);
        if (CollectionUtils.isEmpty(tblActivitiesAddresses)){
            return new ResResult<>(500,"请先设置本次活动的窗口号");
        }

        //将 窗口号*时间段 插入be_sample_units_activities表
        insertBeSampleUnitsActivities(tblActivities, unitsId, tblActivitiesAddresses, peoples, intervalTime, 0);//0-不可预约

        //根据unitsId找到对应的班级
        LinkedList<TblUnits> tblUnits = new LinkedList<>();
        for (Integer unitsId_ : unitsIds) {
            List<TblUnits> tblUnit = tblUnitsMapper.selectUnitsChildren(unitsId_);
            tblUnits.addAll(tblUnit);
        }

        //查找到所有该活动id和sample_address_id对应的被采样单位活动表的记录
        QueryWrapper<BeSampleUnitsActivities> wrapper2 = new QueryWrapper<>();
        wrapper2.allEq(map);
        List<BeSampleUnitsActivities> beSampleUnitsActivities = beSampleUnitsActivitiesMapper.selectList(wrapper2);

        //通过得到的班级的units_id查找对应的用户
        LinkedList<TblUser> tblUsers = selectUserByUnitsId(tblUnits);

        //将用户与采样活动进行一对一插入tbl_order表
        return insertTblOrder(beSampleUnitsActivities, peoples, tblUsers);
    }

    /**
     * 单位进行活动选择(可预约)
     * @param activitiesId
     * @param unitsId
     * @param peoples
     * @param intervalTime
     * @return
     * @throws ParseException
     */
    @Override
    @Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class)//事务：读取已提交数据(会出现不可重复读和幻读)
    public ResResult<?> unitsSelectActivitiesOrder(Integer activitiesId, Integer unitsId, Integer peoples, Integer intervalTime) throws ParseException {

        //通过activitiesId查找对应的活动
        TblActivities tblActivities = tblActivitiesMapper.selectById(activitiesId);
        if (Objects.isNull(tblActivities)) {
            return new ResResult<>(404, "未找到该次活动");
        }

        //通过活动id查找对应的采样地点
        List<TblSampleAddress> tblSampleAddresses = beSampleUnitsActivitiesMapper.showReservationAddress(activitiesId);
        if (CollectionUtils.isEmpty(tblSampleAddresses)){
            return new ResResult<>(500,"请先设置本次活动的窗口号");
        }

        List<TblActivitiesAddress> tblActivitiesAddresses = new ArrayList<>();
        for (TblSampleAddress tblSampleAddress : tblSampleAddresses) {
            //获取活动对应的地点
            List<TblActivitiesAddress> tblActivitiesAddresses_ = tblActivitiesAddressMapper.getWindowsById(activitiesId, tblSampleAddress.getAddressId());
            tblActivitiesAddresses.addAll(tblActivitiesAddresses_);
        }

        //将 窗口号*时间段 插入be_sample_units_activities表
        insertBeSampleUnitsActivities(tblActivities, unitsId, tblActivitiesAddresses, peoples, intervalTime, 1);//1-可预约

        return new ResResult<>(200,"提交成功");
    }

    /**
     * 查找被采样单位的所有叶子节点
     *
     * @param tblUnits
     * @return LinkedList<TblUser>
     */
    public LinkedList<TblUser> selectUserByUnitsId(List<TblUnits> tblUnits) {
        LinkedList<TblUser> tblUsers = new LinkedList<>();
        for (TblUnits tblUnit : tblUnits) {
            //通过单位id（班级..）查找对应的所有用户
            LambdaQueryWrapper<TblUser> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(TblUser::getUnitsId, tblUnit.getUnitsId());
            List<TblUser> tblUser = tblUserMapper.selectList(wrapper);
            tblUsers.addAll(tblUser);
        }
        return tblUsers;
    }

    /**
     * 将 窗口号*时间段 插入be_sample_units_activities表
     *
     * @param tblActivities
     * @param tblActivitiesAddresses
     */
    public void insertBeSampleUnitsActivities(TblActivities tblActivities, Integer unitsId, List<TblActivitiesAddress> tblActivitiesAddresses, Integer peoples, Integer intervalTime, Integer status) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        long time = intervalTime * 60 * 1000L;
        long l = tblActivities.getActivityBeginTime().getTime();
        ArrayList<BeSampleUnitsActivities> beSampleUnitsActivitiesList = new ArrayList<>();
        do {
            for (TblActivitiesAddress tblActivitiesAddress : tblActivitiesAddresses) {
                BeSampleUnitsActivities beSampleUnitsActivities = new BeSampleUnitsActivities();
                beSampleUnitsActivities.setActivitiesId(tblActivities.getActivitiesId());
                beSampleUnitsActivities.setUnitsId(unitsId);
                beSampleUnitsActivities.setSampleAddressId(tblActivitiesAddress.getSampleAddressId());
                beSampleUnitsActivities.setActivitiesAddressId(tblActivitiesAddress.getActivitiesAddressId());
                String format = sdf.format(l);
                Date parse = sdf.parse(format);
                beSampleUnitsActivities.setSampleBeginTime(parse);
                String format2 = sdf.format(l + time);
                Date parse2 = sdf.parse(format2);
                beSampleUnitsActivities.setSampleEndTime(parse2);
                beSampleUnitsActivities.setPeoples(peoples);
                beSampleUnitsActivities.setOrderedPeoples(0);
                beSampleUnitsActivities.setOrderStatus(status);
                //beSampleUnitsActivitiesMapper.insert(beSampleUnitsActivities);
                beSampleUnitsActivitiesList.add(beSampleUnitsActivities);
            }
            l = l + time;
        } while (tblActivities.getActivityEndTime().getTime() > l);
        beSampleUnitsActivitiesService.saveBatch(beSampleUnitsActivitiesList);
    }

    /**
     * 将用户与采样活动进行一对一插入tbl_order表
     */
    public ResResult<?> insertTblOrder(List<BeSampleUnitsActivities> beSampleUnitsActivities, Integer peoples, LinkedList<TblUser> tblUsers) {

        if (beSampleUnitsActivities.size()*peoples < tblUsers.size()){
            return new ResResult<>(500,"设置的人数不足已容纳所有被检测者");
        }
        if (CollectionUtils.isEmpty(beSampleUnitsActivities)){
            return new ResResult<>(500,"活动发布有误，请检测是否设置窗口");
        }
        if (CollectionUtils.isEmpty(tblUsers)){
            return new ResResult<>(500,"未找到该地区的用户");
        }
        int count1 = 0;//tblUsers2下标
        int count2 = 0;//beSampleUnitsActivities下标
        ArrayList<TblOrder> orderList = new ArrayList<>();
        do {
            BeSampleUnitsActivities beSampleUnitsActivity = beSampleUnitsActivities.get(count2);
            for (int i = 0; i < peoples; i++) {
                TblOrder tblOrder = new TblOrder();
                tblOrder.setUserId(tblUsers.get(count1).getUserId());
                tblOrder.setIdNumber(tblUsers.get(count1).getIdNumber());
                tblOrder.setOrderBeginTime(beSampleUnitsActivity.getSampleBeginTime());
                tblOrder.setOrderEndTime(beSampleUnitsActivity.getSampleEndTime());
                tblOrder.setBeSampleId(beSampleUnitsActivity.getBeSampleId());
                tblOrder.setActivitiesId(beSampleUnitsActivity.getActivitiesId());
                tblOrder.setStatus(1); //设为未检测状态
                //tblOrderMapper.insert(tblOrder);
                orderList.add(tblOrder);
                count1++;
                if (count1 == tblUsers.size()) {
                    beSampleUnitsActivitiesMapper.updateOrderPeople(i+1,beSampleUnitsActivity.getBeSampleId());
                    tblOrderService.saveBatch(orderList);
                    return new ResResult<>(200, "提交成功");
                }
            }
            beSampleUnitsActivitiesMapper.updateOrderPeople(peoples,beSampleUnitsActivity.getBeSampleId());
            count2++;
        } while (count2 != beSampleUnitsActivities.size());
        tblOrderService.saveBatch(orderList);
        return new ResResult<>(200, "提交成功");
    }

    @Override
    public Integer updatePeoples(Integer beSampleId, Integer orderedPeoples) {
        return beSampleUnitsActivitiesMapper.updatePeoples(beSampleId, orderedPeoples);
    }

    /**
     * 模糊查询
     *
     * @param currentPage
     * @param pageSize
     * @return
     */
    @Override
    public IPage<BeSampleUnitsActivities> getByPage(int currentPage, int pageSize) {
        LambdaQueryWrapper<BeSampleUnitsActivities> queryWrapper = new LambdaQueryWrapper<>();
//        queryWrapper.like(Strings.isNullOrEmpty(beSampleUnitsActivities.getSampleEndTime().toString()), BeSampleUnitsActivities::getSampleEndTime, beSampleUnitsActivities.getSampleEndTime());
//        queryWrapper.like(Strings.isNullOrEmpty(beSampleUnitsActivities.getSampleBeginTime().toString()), BeSampleUnitsActivities::getSampleBeginTime, beSampleUnitsActivities.getSampleBeginTime());
        IPage<BeSampleUnitsActivities> page = new Page<>(currentPage, pageSize);
        return beSampleUnitsActivitiesMapper.selectPage(page, queryWrapper);
    }

    @Override
    public PageVo<?> getBeSampleUnitsActivitiesByActivitiesId(Integer pageNum, Integer pageSize, BeSampleUnitsActivitiesVo beSampleUnitsActivities, String beginTime, String endTime) {
        Page<BeSampleUnitsActivities> page = new Page<>(pageNum,pageSize);
        IPage<BeSampleUnitsActivities> iPage = beSampleUnitsActivitiesMapper.getBeSampleUnitsActivitiesByActivitiesId(page,beSampleUnitsActivities,beginTime,endTime);
        PageVo<BeSampleUnitsActivities> pageVo = new PageVo<>();
        pageVo.setCurrent((int) iPage.getCurrent());
        pageVo.setSize((int) iPage.getSize());
        pageVo.setList(iPage.getRecords());
        pageVo.setTotal(iPage.getTotal());
        pageVo.setCode(200);
        return pageVo;
    }

    @Override
    public List<BeSampleUnitsActivitiesVo> getBeSampleUnitsActivitiesList(BeSampleUnitsActivitiesVo beSampleUnitsActivities, String beginTime, String endTime) {
        List<BeSampleUnitsActivitiesVo> list = beSampleUnitsActivitiesMapper.getBeSampleUnitsActivitiesList(beSampleUnitsActivities,beginTime,endTime);
        for (BeSampleUnitsActivitiesVo beSampleUnitsActivitiesVo:list) {
            if (beSampleUnitsActivitiesVo.getOrderStatus()==1) {
                beSampleUnitsActivitiesVo.setOrderSta("可预约");
            } else {
                beSampleUnitsActivitiesVo.setOrderSta("不可预约");
            }
        }
        return list;
    }

    /**
     * 分页查询
     *
     * @param currentPage
     * @param pageSize
     * @return
     */
    @Override
    public IPage<BeSampleUnitsActivities> getPages(int currentPage, int pageSize) {
        IPage<BeSampleUnitsActivities> page = new Page<>(currentPage, pageSize);
        return beSampleUnitsActivitiesMapper.selectPage(page, null);
    }
}
